<?php
class DbMongo extends Db{

	function __construct($dbconfig=''){
		$this->dbconfig = $dbconfig;
	}


	//創建連接
	public function connect($mode){
		$config = $this->dbconfig[$mode];
		$dbhost = $config['dbhost'];
		$dbname = $config['dbname'];
		$dbuser = $config['username'];
		$dbpasswd  = $config['password'];
		$pconnect = $config['pconnect'];

		$server = 'mongodb://';
		if(!empty($dbuser)) $server .= $dbuser . ':' . $dbpasswd . '@';
		$server .= $dbhost . '/' . $dbname;
		$options = array();
		if(!empty($pconnect)){
			$options['persist'] = $pconnect;
			if(isset($config['timeout']) && !empty($config['timeout'])){
				$options['timeout'] = intval($config['timeout']);
			}
		}
		$conn = new Mongo($server, $options);
		$db = $conn->selectDB($dbname);

		return $db;
	}


	/** 查詢DB
	* @param String 	$tabname 	表名
	* @param Array		$param	 	參數
	* @param obj		$dbconn		DB link
	* @param String		$fetchmode	PDO:setFetchMode
	* @param int		$debug		0:不顯示查詢語句 1:顯示查詢語句
	* @return Array 	$result $pageinfo
	*/
	public function query($tabname,$param=array(),$dbconn,$fetchmode='',$debug=0){

		$field = isset($param['field']) && !empty($param['field']) ? explode(',', $param['field']) : array();
		$where = isset($param['where']) && !empty($param['where']) ? $param['where'] : array();
		#$group = isset($param['group']) && !empty($param['group']) ? 'group by '.$param['group'] : array();
		$order = isset($param['order']) && !empty($param['order']) ? $param['order'] : array();
		$limit = isset($param['limit']) && !empty($param['limit']) ? (int)$param['limit'] : 0;
		$pagesize = isset($param['pagesize']) && !empty($param['pagesize']) ? (int)$param['pagesize'] : 0;
		$page = isset($param['page']) && !empty($param['page']) ? (int)$param['page'] : 1;

		$coll = $dbconn->selectCollection($tabname);
		$cursor = $coll->find($where, $field);
		#$cursor->snapshot(); #锁定结果集
		if(!empty($order)) $cursor = $cursor->sort($order);
		$this->debug($debug,'$coll->find(' . var_export($where, true) . ', ' . var_export($field, true) . ')');						//debug
		if($pagesize > 0){	//分頁			
			$total = $cursor->count();	//記錄總數
			$pagecount = ($total>0) ? (int)(($total-1)/$pagesize)+1 : 0;
			if($page<=0 || $page>$pagecount){
				$page = 1;
			}
			$pageinfo = array();
			$pageinfo['total'] = $total;
			$pageinfo['pagecount'] = $pagecount;
			$pageinfo['pagesize'] = $pagesize;
			$pageinfo['curpage'] = $page;
			$startpage = ($page-1)*$pagesize;
			$cursor = $cursor->skip($startpage)->limit($pagesize);		

		}else{	//不分頁
			if(!empty($limit)) $cursor = $cursor->limit($limit);		
		}
		
		$result = array();
		switch($fetchmode){
			case 'num':
				foreach($cursor as $v){
					$result[] = array_values($v);
				}
				break;
			case 'hash':
				foreach($cursor as $v){
					$result[] = $v;
				}
				break;
			case 'one':
				if($cursor->hasNext()){
					$result = $cursor->getNext();
				}
				break;
			default:
				foreach($cursor as $v){
					$result[] = array_merge($v, array_values($v));
				}
				break;
		}

		$data = array();
		$data['result'] = $result;
		$data['pageinfo'] = isset($pageinfo) ? $pageinfo : array();
		return $data;
	}


	/** 插入記錄
	* @param String	$tabname	表名
	* @param Array	$data		key=>$value
	* @param obj	$dbconn		DB link
	* @return int insertID
	*/
	public function add($tabname,$data,$dbconn){
		$coll = $dbconn->selectCollection($tabname);
		$auto_increment_coll = $dbconn->selectCollection('ids');
		$auto_increment = $auto_increment_coll->findOne(array('table_name' => $tabname), array('next_autoindex'));
		if(isset($auto_increment['next_autoindex'])){
			$data['id'] = $auto_increment['next_autoindex'];
			$auto_increment_coll->update(array('table_name' => $tabname), array('$inc' => array('next_autoindex' => 1)));
		}else{
			$data['id'] = 1;
			$auto_increment_coll->insert(array('table_name' => $tabname, 'next_autoindex' => 2));
		}
		$result = $coll->insert($data, array('safe' => true));
		return (isset($result['ok']) && !empty($result['ok'])) ? $data['id'] : 0;
	}


	/** 更新記錄
	* @param String $tabname	表名
	* @param Array	$data		$key=>$value or '$set' => array($key=>$value)
	* @param String	$condition	條件
	* @param obj	$dbconn		DB link
	* @return int affected count
	*/
	public function update($tabname,$data,$condition=array(),$dbconn){
		$coll = $dbconn->selectCollection($tabname);
		$update_param = is_array(current($data)) ? $data : array('$set' => $data);
		$result =  $coll->update($condition, $update_param, array('safe' => true, 'multiple' => true));
		return isset($result['n']) ? $result['n'] : 0;
	}
	
	
	/** 刪除記錄
	* @param String $tabname	表名
	* @param String $condition	條件
	* @param obj	$dbconn		DB link
	*/
	public function del($tabname,$condition,$dbconn){
		$coll = $dbconn->selectCollection($tabname);
		$result = $coll->remove($condition);
		return isset($result['n']) ? $result['n'] : 0;
	}


	/** 自定義SQL語句
	* @param String $function_name 	
	* @param Array	$param	 	參數
	* @param obj	$dbconn		DB link
	*/
	public function handle($function_name,$param=array(),$dbconn){
		return call_user_func_array(array($dbconn, $function_name), $param);
	}


	/* 顯示sql語句
	* @param int 	$debug 0/1
	* @param String	$sql
	*/
	private function debug($debug,$sql){
		if($debug==1){
			echo $sql."<br>";
		}
	}

}
?>
